package com.mti.handler;

import com.mti.websocket.SocketSessionRegistry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.socket.WebSocketHandler;
import org.springframework.web.reactive.socket.WebSocketMessage;
import org.springframework.web.reactive.socket.WebSocketSession;
import reactor.core.publisher.Mono;

/**
 *  Websocket消息处理
 *
 * @author yangsp
 * @since 2019-03-22
 */
@Component
@Slf4j
public class MessageHandler implements WebSocketHandler {

    @Autowired
    private SocketSessionRegistry sessionRegistry;

    @Override
    public Mono<Void> handle(WebSocketSession session) {

        if(session == null || session.receive() == null){
            return null;
        }
        return session.receive().doOnSubscribe(s -> {
            log.info("发起连接:{}",s);
            sessionRegistry.registerSession(session);
        }).doOnTerminate(() -> {
           sessionRegistry.unregisterSession(session);
           log.info("doOnTerminate");
        }).doOnComplete(() -> {
            log.info("doOnComplete");
        }).doOnCancel(() -> {
            log.info("doOnCancel");
        }).doOnNext(message -> {
            if(message.getType().equals(WebSocketMessage.Type.BINARY)){
                log.info("收到二进制消息");
            }else if(message.getType().equals(WebSocketMessage.Type.TEXT)){
                String content = message.getPayloadAsText();
                log.info("收到文本消息:{}",content);
                //session.send(Flux.just(session.textMessage("收到了你的消息:"+content))).then().toProcessor();
            }else if(message.getType().equals(WebSocketMessage.Type.PING)){
                //session.send(Flux.just(session.pongMessage(s -> s.wrap(new byte[256]))));
                log.info("收到ping消息");
            }else if(message.getType().equals(WebSocketMessage.Type.PONG)){
                log.info("收到pong消息");
            }
        }).doOnError(e -> {
            e.printStackTrace();
            log.error("doOnError");
        }).doOnRequest(r -> {
            log.info("doOnRequest");
        }).then();
    }

}
